{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nDs-Mp5MJikn"
   },
   "source": [
    "# Building a Simple Movie Recommender with LanceDB Cloud"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "eJWtFbhzJ9_b"
   },
   "source": [
    "## Credentials\n",
    "\n",
    "Copy and paste the project name and the api key from your project page.\n",
    "These will be used later to [connect to LanceDB Cloud](#scroll-to=5q8m6GMD7sGu)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "v1tlHcnMmJEh"
   },
   "outputs": [],
   "source": [
    "project_slug = \"your-project-slug\"  # @param {type:\"string\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "iCMDeJ8jma1z"
   },
   "outputs": [],
   "source": [
    "api_key = \"sk_...\"  # @param {type:\"string\"}!"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "You can also set the LANCEDB_API_KEY as an environment variable with one of the options below"
   ],
   "metadata": {
    "id": "a27ICh-1rONc"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "!export LANCEDB_API_KEY=\"sk_...\""
   ],
   "metadata": {
    "id": "iYCNW6rHriOS"
   },
   "execution_count": 27,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "import os\n",
    "import getpass\n",
    "\n",
    "os.environ[\"LANCEDB_API_KEY\"] = getpass.getpass(\"Enter Your LANCEDB API Key:\")"
   ],
   "metadata": {
    "id": "KS93TA5UsPit"
   },
   "execution_count": 22,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DAyxhybfKTQu"
   },
   "source": [
    "## Download the raw data\n",
    "Download and unzip the dataset from [MovieLens](https://grouplens.org/datasets/movielens/latest/). The example uses the 100k small dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3jXSVspr7sGe",
    "vscode": {
     "languageId": "shellscript"
    },
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "outputId": "f6198e67-0504-4a69-bf90-87817108ab17"
   },
   "outputs": [
    {
     "metadata": {
      "tags": null
     },
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n",
      "                                 Dload  Upload   Total   Spent    Left  Speed\n",
      "100  955k  100  955k    0     0   426k      0  0:00:02  0:00:02 --:--:--  426k\n",
      "Archive:  ml-latest-small.zip\n",
      "replace ml-latest-small/links.csv? [y]es, [n]o, [A]ll, [N]one, [r]ename: "
     ]
    }
   ],
   "source": [
    "!curl https://files.grouplens.org/datasets/movielens/ml-latest-small.zip -o ml-latest-small.zip\n",
    "!unzip ml-latest-small.zip"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TgqEEYd38kED"
   },
   "source": [
    "## Let's start by installing and importing the libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "2jXSVspr7sGe"
   },
   "outputs": [],
   "source": [
    "!pip install lancedb pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "yLD8vsMB7sGh"
   },
   "outputs": [],
   "source": [
    "import lancedb\n",
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xSqPUBYw8s30"
   },
   "source": [
    "## Load and unpack the dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "apWYq2AZ7sGi"
   },
   "source": [
    "After unzipping the dataset from MovieLens, we'll load the user ratings into a dataframe `ratings`. Since we don't need timestamp, we can drop that column. We also have to prepare the columns in proper formats."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "y9Fn7l9x7sGj",
    "outputId": "ab559def-6893-473c-8be7-090f98342ad3",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "        user id  movie id  rating\n",
       "1             1         1     4.0\n",
       "2             1         3     4.0\n",
       "3             1         6     4.0\n",
       "4             1        47     5.0\n",
       "5             1        50     5.0\n",
       "...         ...       ...     ...\n",
       "100832      610    166534     4.0\n",
       "100833      610    168248     5.0\n",
       "100834      610    168250     5.0\n",
       "100835      610    168252     5.0\n",
       "100836      610    170875     3.0\n",
       "\n",
       "[100836 rows x 3 columns]"
      ],
      "text/html": [
       "\n",
       "  <div id=\"df-98fb6df4-439b-4c58-98ce-eafee99e785e\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user id</th>\n",
       "      <th>movie id</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>47</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>1</td>\n",
       "      <td>50</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100832</th>\n",
       "      <td>610</td>\n",
       "      <td>166534</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100833</th>\n",
       "      <td>610</td>\n",
       "      <td>168248</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100834</th>\n",
       "      <td>610</td>\n",
       "      <td>168250</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100835</th>\n",
       "      <td>610</td>\n",
       "      <td>168252</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100836</th>\n",
       "      <td>610</td>\n",
       "      <td>170875</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>100836 rows × 3 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-98fb6df4-439b-4c58-98ce-eafee99e785e')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-98fb6df4-439b-4c58-98ce-eafee99e785e button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-98fb6df4-439b-4c58-98ce-eafee99e785e');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-8112b5c6-e5ef-419d-8bc7-bebc2fb88b61\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-8112b5c6-e5ef-419d-8bc7-bebc2fb88b61')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-8112b5c6-e5ef-419d-8bc7-bebc2fb88b61 button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ]
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "source": [
    "ratings = pd.read_csv(\n",
    "    \"./ml-latest-small/ratings.csv\",\n",
    "    header=None,\n",
    "    names=[\"user id\", \"movie id\", \"rating\", \"timestamp\"],\n",
    ")\n",
    "ratings = ratings.drop(columns=[\"timestamp\"])\n",
    "ratings = ratings.drop(0)\n",
    "ratings[\"rating\"] = ratings[\"rating\"].values.astype(np.float32)\n",
    "ratings[\"user id\"] = ratings[\"user id\"].values.astype(np.int32)\n",
    "ratings[\"movie id\"] = ratings[\"movie id\"].values.astype(np.int32)\n",
    "ratings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "btYN_c0q7sGl"
   },
   "source": [
    "We can now create a matrix of user ratings, where each row represents a user and each column represents a movie."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "Kmuv9gxf7sGm",
    "outputId": "aae551ea-5269-4457-dae9-fadaad6db3ae",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 455
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "movie id  1       2       3       4       5       6       7       8       \\\n",
       "user id                                                                    \n",
       "1            4.0     0.0     4.0     0.0     0.0     4.0     0.0     0.0   \n",
       "2            0.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "3            0.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "4            0.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "5            4.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "...          ...     ...     ...     ...     ...     ...     ...     ...   \n",
       "606          2.5     0.0     0.0     0.0     0.0     0.0     2.5     0.0   \n",
       "607          4.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "608          2.5     2.0     2.0     0.0     0.0     0.0     0.0     0.0   \n",
       "609          3.0     0.0     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "610          5.0     0.0     0.0     0.0     0.0     5.0     0.0     0.0   \n",
       "\n",
       "movie id  9       10      ...  193565  193567  193571  193573  193579  193581  \\\n",
       "user id                   ...                                                   \n",
       "1            0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "2            0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "3            0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "4            0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "5            0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "...          ...     ...  ...     ...     ...     ...     ...     ...     ...   \n",
       "606          0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "607          0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "608          0.0     4.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "609          0.0     4.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "610          0.0     0.0  ...     0.0     0.0     0.0     0.0     0.0     0.0   \n",
       "\n",
       "movie id  193583  193585  193587  193609  \n",
       "user id                                   \n",
       "1            0.0     0.0     0.0     0.0  \n",
       "2            0.0     0.0     0.0     0.0  \n",
       "3            0.0     0.0     0.0     0.0  \n",
       "4            0.0     0.0     0.0     0.0  \n",
       "5            0.0     0.0     0.0     0.0  \n",
       "...          ...     ...     ...     ...  \n",
       "606          0.0     0.0     0.0     0.0  \n",
       "607          0.0     0.0     0.0     0.0  \n",
       "608          0.0     0.0     0.0     0.0  \n",
       "609          0.0     0.0     0.0     0.0  \n",
       "610          0.0     0.0     0.0     0.0  \n",
       "\n",
       "[610 rows x 9724 columns]"
      ],
      "text/html": [
       "\n",
       "  <div id=\"df-58478072-b8b8-49a0-9cb6-d46e3134fdcb\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>movie id</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>10</th>\n",
       "      <th>...</th>\n",
       "      <th>193565</th>\n",
       "      <th>193567</th>\n",
       "      <th>193571</th>\n",
       "      <th>193573</th>\n",
       "      <th>193579</th>\n",
       "      <th>193581</th>\n",
       "      <th>193583</th>\n",
       "      <th>193585</th>\n",
       "      <th>193587</th>\n",
       "      <th>193609</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>user id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>606</th>\n",
       "      <td>2.5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>607</th>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>608</th>\n",
       "      <td>2.5</td>\n",
       "      <td>2.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>609</th>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>610</th>\n",
       "      <td>5.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>...</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>610 rows × 9724 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-58478072-b8b8-49a0-9cb6-d46e3134fdcb')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-58478072-b8b8-49a0-9cb6-d46e3134fdcb button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-58478072-b8b8-49a0-9cb6-d46e3134fdcb');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-623f087b-78d7-4c16-a916-ba8476a782e6\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-623f087b-78d7-4c16-a916-ba8476a782e6')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-623f087b-78d7-4c16-a916-ba8476a782e6 button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ]
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "source": [
    "reviewmatrix = ratings.pivot(\n",
    "    index=\"user id\", columns=\"movie id\", values=\"rating\"\n",
    ").fillna(0)\n",
    "reviewmatrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0a3qCjRN7sGn"
   },
   "source": [
    "Now, we apply the **SVD**. `vh` represents the orthogonal matrix that describes the relationship between columns of the original matrix. Because the\n",
    "\n",
    "---\n",
    "\n",
    "columns of `vh` correspond to the movies, we can flip it to get the movie embeddings on the rows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "mGWO8R0i7sGp",
    "outputId": "1720258d-4e49-4490-ab6c-e32a59c1fa23",
    "colab": {
     "base_uri": "https://localhost:8080/"
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "array([[-7.0449896e-02, -3.8539346e-02, -1.5912922e-02, ...,\n",
       "        -6.4683605e-05, -6.4683605e-05, -2.7172931e-04],\n",
       "       [ 2.7591195e-02,  2.0666271e-03,  2.4714615e-02, ...,\n",
       "        -5.9758622e-04, -5.9758622e-04, -1.2723620e-03],\n",
       "       [-7.8443885e-02, -5.6844711e-02, -1.8005114e-02, ...,\n",
       "         8.7109387e-05,  8.7109387e-05, -1.2283334e-04],\n",
       "       ...,\n",
       "       [ 2.0168955e-02,  1.3377998e-02, -1.9083519e-02, ...,\n",
       "        -1.9121233e-03, -1.9121233e-03, -2.1089672e-03],\n",
       "       [ 3.5461895e-02, -1.0232525e-01, -1.1956284e-02, ...,\n",
       "         9.4549108e-04,  9.4549108e-04,  2.5773358e-03],\n",
       "       [ 6.7939058e-02,  1.2740049e-02, -2.3002084e-02, ...,\n",
       "        -9.3789837e-05, -9.3789837e-05, -1.9718462e-03]], dtype=float32)"
      ]
     },
     "metadata": {},
     "execution_count": 10
    }
   ],
   "source": [
    "matrix = reviewmatrix.values\n",
    "u, s, vh = np.linalg.svd(matrix, full_matrices=False)\n",
    "vh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "a7FYDE5P7sGs",
    "outputId": "9cb4a012-72f6-4a7f-e1a4-69869a92bd38",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 444
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "           0         1         2         3         4         5         6    \\\n",
       "0    -0.070450  0.027591 -0.078444 -0.001684  0.012210  0.032511 -0.064926   \n",
       "1    -0.038539  0.002067 -0.056845  0.050673  0.019879 -0.003510 -0.032134   \n",
       "2    -0.015913  0.024715 -0.018005  0.037453 -0.000156 -0.005317  0.010490   \n",
       "3    -0.000871  0.003581 -0.004994  0.001403  0.004760 -0.005955 -0.001583   \n",
       "4    -0.011360  0.011562 -0.024578  0.025911  0.024032 -0.011359 -0.009566   \n",
       "...        ...       ...       ...       ...       ...       ...       ...   \n",
       "9719 -0.000074 -0.000683  0.000100 -0.000056 -0.000161 -0.001114 -0.001347   \n",
       "9720 -0.000065 -0.000598  0.000087 -0.000049 -0.000141 -0.000975 -0.001179   \n",
       "9721 -0.000065 -0.000598  0.000087 -0.000049 -0.000141 -0.000975 -0.001179   \n",
       "9722 -0.000065 -0.000598  0.000087 -0.000049 -0.000141 -0.000975 -0.001179   \n",
       "9723 -0.000272 -0.001272 -0.000123 -0.000895  0.000726 -0.000508  0.000391   \n",
       "\n",
       "           7         8         9    ...       600       601       602  \\\n",
       "0     0.017924 -0.009497  0.012267  ...  0.020612 -0.019381 -0.057998   \n",
       "1     0.031154  0.027948  0.002091  ... -0.088892 -0.096330  0.050715   \n",
       "2     0.004421 -0.026932  0.016773  ... -0.028688  0.002024  0.012164   \n",
       "3     0.004299 -0.000654  0.000138  ...  0.031561  0.031872  0.077064   \n",
       "4     0.010664 -0.010917  0.010871  ... -0.019130  0.018233  0.093399   \n",
       "...        ...       ...       ...  ...       ...       ...       ...   \n",
       "9719 -0.000580 -0.000080 -0.000409  ... -0.001130  0.001340  0.000037   \n",
       "9720 -0.000507 -0.000070 -0.000357  ... -0.000989  0.001173  0.000032   \n",
       "9721 -0.000507 -0.000070 -0.000357  ... -0.000989  0.001173  0.000032   \n",
       "9722 -0.000507 -0.000070 -0.000357  ... -0.000989  0.001173  0.000032   \n",
       "9723 -0.000391 -0.000643  0.001185  ... -0.000378  0.005020  0.001524   \n",
       "\n",
       "           603       604       605       606       607       608       609  \n",
       "0    -0.027171 -0.006926  0.059270  0.110072  0.020169  0.035462  0.067939  \n",
       "1     0.057505 -0.067907  0.080617 -0.105529  0.013378 -0.102325  0.012740  \n",
       "2     0.040334 -0.016997  0.041067 -0.002768 -0.019084 -0.011956 -0.023002  \n",
       "3     0.009637  0.001437 -0.003798 -0.015851 -0.007668 -0.007170  0.049587  \n",
       "4     0.039459 -0.025126  0.031353  0.004618 -0.055738  0.016194 -0.009322  \n",
       "...        ...       ...       ...       ...       ...       ...       ...  \n",
       "9719  0.000423  0.001391  0.000826 -0.001491 -0.002185  0.001081 -0.000107  \n",
       "9720  0.000370  0.001217  0.000722 -0.001305 -0.001912  0.000945 -0.000094  \n",
       "9721  0.000370  0.001217  0.000722 -0.001305 -0.001912  0.000945 -0.000094  \n",
       "9722  0.000370  0.001217  0.000722 -0.001305 -0.001912  0.000945 -0.000094  \n",
       "9723  0.002238 -0.000477 -0.002297  0.001557 -0.002109  0.002577 -0.001972  \n",
       "\n",
       "[9724 rows x 610 columns]"
      ],
      "text/html": [
       "\n",
       "  <div id=\"df-89275df8-7ee4-417b-aef3-f803e24eb17d\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>...</th>\n",
       "      <th>600</th>\n",
       "      <th>601</th>\n",
       "      <th>602</th>\n",
       "      <th>603</th>\n",
       "      <th>604</th>\n",
       "      <th>605</th>\n",
       "      <th>606</th>\n",
       "      <th>607</th>\n",
       "      <th>608</th>\n",
       "      <th>609</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.070450</td>\n",
       "      <td>0.027591</td>\n",
       "      <td>-0.078444</td>\n",
       "      <td>-0.001684</td>\n",
       "      <td>0.012210</td>\n",
       "      <td>0.032511</td>\n",
       "      <td>-0.064926</td>\n",
       "      <td>0.017924</td>\n",
       "      <td>-0.009497</td>\n",
       "      <td>0.012267</td>\n",
       "      <td>...</td>\n",
       "      <td>0.020612</td>\n",
       "      <td>-0.019381</td>\n",
       "      <td>-0.057998</td>\n",
       "      <td>-0.027171</td>\n",
       "      <td>-0.006926</td>\n",
       "      <td>0.059270</td>\n",
       "      <td>0.110072</td>\n",
       "      <td>0.020169</td>\n",
       "      <td>0.035462</td>\n",
       "      <td>0.067939</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.038539</td>\n",
       "      <td>0.002067</td>\n",
       "      <td>-0.056845</td>\n",
       "      <td>0.050673</td>\n",
       "      <td>0.019879</td>\n",
       "      <td>-0.003510</td>\n",
       "      <td>-0.032134</td>\n",
       "      <td>0.031154</td>\n",
       "      <td>0.027948</td>\n",
       "      <td>0.002091</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.088892</td>\n",
       "      <td>-0.096330</td>\n",
       "      <td>0.050715</td>\n",
       "      <td>0.057505</td>\n",
       "      <td>-0.067907</td>\n",
       "      <td>0.080617</td>\n",
       "      <td>-0.105529</td>\n",
       "      <td>0.013378</td>\n",
       "      <td>-0.102325</td>\n",
       "      <td>0.012740</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.015913</td>\n",
       "      <td>0.024715</td>\n",
       "      <td>-0.018005</td>\n",
       "      <td>0.037453</td>\n",
       "      <td>-0.000156</td>\n",
       "      <td>-0.005317</td>\n",
       "      <td>0.010490</td>\n",
       "      <td>0.004421</td>\n",
       "      <td>-0.026932</td>\n",
       "      <td>0.016773</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.028688</td>\n",
       "      <td>0.002024</td>\n",
       "      <td>0.012164</td>\n",
       "      <td>0.040334</td>\n",
       "      <td>-0.016997</td>\n",
       "      <td>0.041067</td>\n",
       "      <td>-0.002768</td>\n",
       "      <td>-0.019084</td>\n",
       "      <td>-0.011956</td>\n",
       "      <td>-0.023002</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.000871</td>\n",
       "      <td>0.003581</td>\n",
       "      <td>-0.004994</td>\n",
       "      <td>0.001403</td>\n",
       "      <td>0.004760</td>\n",
       "      <td>-0.005955</td>\n",
       "      <td>-0.001583</td>\n",
       "      <td>0.004299</td>\n",
       "      <td>-0.000654</td>\n",
       "      <td>0.000138</td>\n",
       "      <td>...</td>\n",
       "      <td>0.031561</td>\n",
       "      <td>0.031872</td>\n",
       "      <td>0.077064</td>\n",
       "      <td>0.009637</td>\n",
       "      <td>0.001437</td>\n",
       "      <td>-0.003798</td>\n",
       "      <td>-0.015851</td>\n",
       "      <td>-0.007668</td>\n",
       "      <td>-0.007170</td>\n",
       "      <td>0.049587</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.011360</td>\n",
       "      <td>0.011562</td>\n",
       "      <td>-0.024578</td>\n",
       "      <td>0.025911</td>\n",
       "      <td>0.024032</td>\n",
       "      <td>-0.011359</td>\n",
       "      <td>-0.009566</td>\n",
       "      <td>0.010664</td>\n",
       "      <td>-0.010917</td>\n",
       "      <td>0.010871</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.019130</td>\n",
       "      <td>0.018233</td>\n",
       "      <td>0.093399</td>\n",
       "      <td>0.039459</td>\n",
       "      <td>-0.025126</td>\n",
       "      <td>0.031353</td>\n",
       "      <td>0.004618</td>\n",
       "      <td>-0.055738</td>\n",
       "      <td>0.016194</td>\n",
       "      <td>-0.009322</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9719</th>\n",
       "      <td>-0.000074</td>\n",
       "      <td>-0.000683</td>\n",
       "      <td>0.000100</td>\n",
       "      <td>-0.000056</td>\n",
       "      <td>-0.000161</td>\n",
       "      <td>-0.001114</td>\n",
       "      <td>-0.001347</td>\n",
       "      <td>-0.000580</td>\n",
       "      <td>-0.000080</td>\n",
       "      <td>-0.000409</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.001130</td>\n",
       "      <td>0.001340</td>\n",
       "      <td>0.000037</td>\n",
       "      <td>0.000423</td>\n",
       "      <td>0.001391</td>\n",
       "      <td>0.000826</td>\n",
       "      <td>-0.001491</td>\n",
       "      <td>-0.002185</td>\n",
       "      <td>0.001081</td>\n",
       "      <td>-0.000107</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9720</th>\n",
       "      <td>-0.000065</td>\n",
       "      <td>-0.000598</td>\n",
       "      <td>0.000087</td>\n",
       "      <td>-0.000049</td>\n",
       "      <td>-0.000141</td>\n",
       "      <td>-0.000975</td>\n",
       "      <td>-0.001179</td>\n",
       "      <td>-0.000507</td>\n",
       "      <td>-0.000070</td>\n",
       "      <td>-0.000357</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.000989</td>\n",
       "      <td>0.001173</td>\n",
       "      <td>0.000032</td>\n",
       "      <td>0.000370</td>\n",
       "      <td>0.001217</td>\n",
       "      <td>0.000722</td>\n",
       "      <td>-0.001305</td>\n",
       "      <td>-0.001912</td>\n",
       "      <td>0.000945</td>\n",
       "      <td>-0.000094</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9721</th>\n",
       "      <td>-0.000065</td>\n",
       "      <td>-0.000598</td>\n",
       "      <td>0.000087</td>\n",
       "      <td>-0.000049</td>\n",
       "      <td>-0.000141</td>\n",
       "      <td>-0.000975</td>\n",
       "      <td>-0.001179</td>\n",
       "      <td>-0.000507</td>\n",
       "      <td>-0.000070</td>\n",
       "      <td>-0.000357</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.000989</td>\n",
       "      <td>0.001173</td>\n",
       "      <td>0.000032</td>\n",
       "      <td>0.000370</td>\n",
       "      <td>0.001217</td>\n",
       "      <td>0.000722</td>\n",
       "      <td>-0.001305</td>\n",
       "      <td>-0.001912</td>\n",
       "      <td>0.000945</td>\n",
       "      <td>-0.000094</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9722</th>\n",
       "      <td>-0.000065</td>\n",
       "      <td>-0.000598</td>\n",
       "      <td>0.000087</td>\n",
       "      <td>-0.000049</td>\n",
       "      <td>-0.000141</td>\n",
       "      <td>-0.000975</td>\n",
       "      <td>-0.001179</td>\n",
       "      <td>-0.000507</td>\n",
       "      <td>-0.000070</td>\n",
       "      <td>-0.000357</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.000989</td>\n",
       "      <td>0.001173</td>\n",
       "      <td>0.000032</td>\n",
       "      <td>0.000370</td>\n",
       "      <td>0.001217</td>\n",
       "      <td>0.000722</td>\n",
       "      <td>-0.001305</td>\n",
       "      <td>-0.001912</td>\n",
       "      <td>0.000945</td>\n",
       "      <td>-0.000094</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9723</th>\n",
       "      <td>-0.000272</td>\n",
       "      <td>-0.001272</td>\n",
       "      <td>-0.000123</td>\n",
       "      <td>-0.000895</td>\n",
       "      <td>0.000726</td>\n",
       "      <td>-0.000508</td>\n",
       "      <td>0.000391</td>\n",
       "      <td>-0.000391</td>\n",
       "      <td>-0.000643</td>\n",
       "      <td>0.001185</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.000378</td>\n",
       "      <td>0.005020</td>\n",
       "      <td>0.001524</td>\n",
       "      <td>0.002238</td>\n",
       "      <td>-0.000477</td>\n",
       "      <td>-0.002297</td>\n",
       "      <td>0.001557</td>\n",
       "      <td>-0.002109</td>\n",
       "      <td>0.002577</td>\n",
       "      <td>-0.001972</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>9724 rows × 610 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-89275df8-7ee4-417b-aef3-f803e24eb17d')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-89275df8-7ee4-417b-aef3-f803e24eb17d button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-89275df8-7ee4-417b-aef3-f803e24eb17d');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-0d4aa3a6-c346-4f5c-b51d-a715a6efc08f\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-0d4aa3a6-c346-4f5c-b51d-a715a6efc08f')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-0d4aa3a6-c346-4f5c-b51d-a715a6efc08f button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ]
     },
     "metadata": {},
     "execution_count": 11
    }
   ],
   "source": [
    "vectors = np.rot90(np.fliplr(vh))\n",
    "pd.DataFrame(vectors)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "76aNsoY_7sGt"
   },
   "source": [
    "Now, let's take the movies dataset to gather the **metadata** for each movie. We'll create an array `data` that contains all this information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "9qbdp3mq7sGu",
    "outputId": "55dbb42e-35ed-42e9-c1ac-ae82da2e925b",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "      movie id                                      title  \\\n",
       "0            1                           Toy Story (1995)   \n",
       "1            2                             Jumanji (1995)   \n",
       "2            3                    Grumpier Old Men (1995)   \n",
       "3            4                   Waiting to Exhale (1995)   \n",
       "4            5         Father of the Bride Part II (1995)   \n",
       "...        ...                                        ...   \n",
       "9737    193581  Black Butler: Book of the Atlantic (2017)   \n",
       "9738    193583               No Game No Life: Zero (2017)   \n",
       "9739    193585                               Flint (2017)   \n",
       "9740    193587        Bungo Stray Dogs: Dead Apple (2018)   \n",
       "9741    193609        Andrew Dice Clay: Dice Rules (1991)   \n",
       "\n",
       "                                           genres  \n",
       "0     Adventure|Animation|Children|Comedy|Fantasy  \n",
       "1                      Adventure|Children|Fantasy  \n",
       "2                                  Comedy|Romance  \n",
       "3                            Comedy|Drama|Romance  \n",
       "4                                          Comedy  \n",
       "...                                           ...  \n",
       "9737              Action|Animation|Comedy|Fantasy  \n",
       "9738                     Animation|Comedy|Fantasy  \n",
       "9739                                        Drama  \n",
       "9740                             Action|Animation  \n",
       "9741                                       Comedy  \n",
       "\n",
       "[9724 rows x 3 columns]"
      ],
      "text/html": [
       "\n",
       "  <div id=\"df-675c8d6d-647a-4ae6-bffc-2d324fdb6bd5\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>movie id</th>\n",
       "      <th>title</th>\n",
       "      <th>genres</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Toy Story (1995)</td>\n",
       "      <td>Adventure|Animation|Children|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>Jumanji (1995)</td>\n",
       "      <td>Adventure|Children|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Grumpier Old Men (1995)</td>\n",
       "      <td>Comedy|Romance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Waiting to Exhale (1995)</td>\n",
       "      <td>Comedy|Drama|Romance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Father of the Bride Part II (1995)</td>\n",
       "      <td>Comedy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9737</th>\n",
       "      <td>193581</td>\n",
       "      <td>Black Butler: Book of the Atlantic (2017)</td>\n",
       "      <td>Action|Animation|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9738</th>\n",
       "      <td>193583</td>\n",
       "      <td>No Game No Life: Zero (2017)</td>\n",
       "      <td>Animation|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9739</th>\n",
       "      <td>193585</td>\n",
       "      <td>Flint (2017)</td>\n",
       "      <td>Drama</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9740</th>\n",
       "      <td>193587</td>\n",
       "      <td>Bungo Stray Dogs: Dead Apple (2018)</td>\n",
       "      <td>Action|Animation</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9741</th>\n",
       "      <td>193609</td>\n",
       "      <td>Andrew Dice Clay: Dice Rules (1991)</td>\n",
       "      <td>Comedy</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>9724 rows × 3 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-675c8d6d-647a-4ae6-bffc-2d324fdb6bd5')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-675c8d6d-647a-4ae6-bffc-2d324fdb6bd5 button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-675c8d6d-647a-4ae6-bffc-2d324fdb6bd5');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-38e5fcd2-b300-49be-9162-072c08604dda\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-38e5fcd2-b300-49be-9162-072c08604dda')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-38e5fcd2-b300-49be-9162-072c08604dda button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "movies = pd.read_csv(\n",
    "    \"./ml-latest-small/movies.csv\", header=0, names=[\"movie id\", \"title\", \"genres\"]\n",
    ")\n",
    "movies = movies[movies[\"movie id\"].isin(reviewmatrix.columns)]\n",
    "movies"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LRu_3sM39D0Q"
   },
   "source": [
    "## Let's see some data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "duhgOmTq7sGu",
    "outputId": "8fba508c-ded5-4650-996a-142f18e9ed59",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 424
    }
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "          id                                      title  \\\n",
       "0          1                           Toy Story (1995)   \n",
       "1          2                             Jumanji (1995)   \n",
       "2          3                    Grumpier Old Men (1995)   \n",
       "3          4                   Waiting to Exhale (1995)   \n",
       "4          5         Father of the Bride Part II (1995)   \n",
       "...      ...                                        ...   \n",
       "9719  193581  Black Butler: Book of the Atlantic (2017)   \n",
       "9720  193583               No Game No Life: Zero (2017)   \n",
       "9721  193585                               Flint (2017)   \n",
       "9722  193587        Bungo Stray Dogs: Dead Apple (2018)   \n",
       "9723  193609        Andrew Dice Clay: Dice Rules (1991)   \n",
       "\n",
       "                                                 vector  \\\n",
       "0     [-0.070449896, 0.027591195, -0.078443885, -0.0...   \n",
       "1     [-0.038539346, 0.0020666271, -0.05684471, 0.05...   \n",
       "2     [-0.015912922, 0.024714615, -0.018005114, 0.03...   \n",
       "3     [-0.00087145035, 0.0035811856, -0.0049938704, ...   \n",
       "4     [-0.011360065, 0.011561904, -0.024578463, 0.02...   \n",
       "...                                                 ...   \n",
       "9719  [-7.392412e-05, -0.0006829557, 9.955359e-05, -...   \n",
       "9720  [-6.4683605e-05, -0.0005975862, 8.710939e-05, ...   \n",
       "9721  [-6.4683605e-05, -0.0005975862, 8.710939e-05, ...   \n",
       "9722  [-6.4683605e-05, -0.0005975862, 8.710939e-05, ...   \n",
       "9723  [-0.0002717293, -0.001272362, -0.00012283334, ...   \n",
       "\n",
       "                                            genre  \n",
       "0     Adventure|Animation|Children|Comedy|Fantasy  \n",
       "1                      Adventure|Children|Fantasy  \n",
       "2                                  Comedy|Romance  \n",
       "3                            Comedy|Drama|Romance  \n",
       "4                                          Comedy  \n",
       "...                                           ...  \n",
       "9719              Action|Animation|Comedy|Fantasy  \n",
       "9720                     Animation|Comedy|Fantasy  \n",
       "9721                                        Drama  \n",
       "9722                             Action|Animation  \n",
       "9723                                       Comedy  \n",
       "\n",
       "[9724 rows x 4 columns]"
      ],
      "text/html": [
       "\n",
       "  <div id=\"df-8f8c6d0a-2c9e-4c10-848c-804232d3715b\" class=\"colab-df-container\">\n",
       "    <div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>title</th>\n",
       "      <th>vector</th>\n",
       "      <th>genre</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Toy Story (1995)</td>\n",
       "      <td>[-0.070449896, 0.027591195, -0.078443885, -0.0...</td>\n",
       "      <td>Adventure|Animation|Children|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>Jumanji (1995)</td>\n",
       "      <td>[-0.038539346, 0.0020666271, -0.05684471, 0.05...</td>\n",
       "      <td>Adventure|Children|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Grumpier Old Men (1995)</td>\n",
       "      <td>[-0.015912922, 0.024714615, -0.018005114, 0.03...</td>\n",
       "      <td>Comedy|Romance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>Waiting to Exhale (1995)</td>\n",
       "      <td>[-0.00087145035, 0.0035811856, -0.0049938704, ...</td>\n",
       "      <td>Comedy|Drama|Romance</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Father of the Bride Part II (1995)</td>\n",
       "      <td>[-0.011360065, 0.011561904, -0.024578463, 0.02...</td>\n",
       "      <td>Comedy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9719</th>\n",
       "      <td>193581</td>\n",
       "      <td>Black Butler: Book of the Atlantic (2017)</td>\n",
       "      <td>[-7.392412e-05, -0.0006829557, 9.955359e-05, -...</td>\n",
       "      <td>Action|Animation|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9720</th>\n",
       "      <td>193583</td>\n",
       "      <td>No Game No Life: Zero (2017)</td>\n",
       "      <td>[-6.4683605e-05, -0.0005975862, 8.710939e-05, ...</td>\n",
       "      <td>Animation|Comedy|Fantasy</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9721</th>\n",
       "      <td>193585</td>\n",
       "      <td>Flint (2017)</td>\n",
       "      <td>[-6.4683605e-05, -0.0005975862, 8.710939e-05, ...</td>\n",
       "      <td>Drama</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9722</th>\n",
       "      <td>193587</td>\n",
       "      <td>Bungo Stray Dogs: Dead Apple (2018)</td>\n",
       "      <td>[-6.4683605e-05, -0.0005975862, 8.710939e-05, ...</td>\n",
       "      <td>Action|Animation</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9723</th>\n",
       "      <td>193609</td>\n",
       "      <td>Andrew Dice Clay: Dice Rules (1991)</td>\n",
       "      <td>[-0.0002717293, -0.001272362, -0.00012283334, ...</td>\n",
       "      <td>Comedy</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>9724 rows × 4 columns</p>\n",
       "</div>\n",
       "    <div class=\"colab-df-buttons\">\n",
       "\n",
       "  <div class=\"colab-df-container\">\n",
       "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-8f8c6d0a-2c9e-4c10-848c-804232d3715b')\"\n",
       "            title=\"Convert this dataframe to an interactive table.\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
       "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
       "  </svg>\n",
       "    </button>\n",
       "\n",
       "  <style>\n",
       "    .colab-df-container {\n",
       "      display:flex;\n",
       "      gap: 12px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert {\n",
       "      background-color: #E8F0FE;\n",
       "      border: none;\n",
       "      border-radius: 50%;\n",
       "      cursor: pointer;\n",
       "      display: none;\n",
       "      fill: #1967D2;\n",
       "      height: 32px;\n",
       "      padding: 0 0 0 0;\n",
       "      width: 32px;\n",
       "    }\n",
       "\n",
       "    .colab-df-convert:hover {\n",
       "      background-color: #E2EBFA;\n",
       "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "      fill: #174EA6;\n",
       "    }\n",
       "\n",
       "    .colab-df-buttons div {\n",
       "      margin-bottom: 4px;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert {\n",
       "      background-color: #3B4455;\n",
       "      fill: #D2E3FC;\n",
       "    }\n",
       "\n",
       "    [theme=dark] .colab-df-convert:hover {\n",
       "      background-color: #434B5C;\n",
       "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
       "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
       "      fill: #FFFFFF;\n",
       "    }\n",
       "  </style>\n",
       "\n",
       "    <script>\n",
       "      const buttonEl =\n",
       "        document.querySelector('#df-8f8c6d0a-2c9e-4c10-848c-804232d3715b button.colab-df-convert');\n",
       "      buttonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "\n",
       "      async function convertToInteractive(key) {\n",
       "        const element = document.querySelector('#df-8f8c6d0a-2c9e-4c10-848c-804232d3715b');\n",
       "        const dataTable =\n",
       "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
       "                                                    [key], {});\n",
       "        if (!dataTable) return;\n",
       "\n",
       "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
       "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
       "          + ' to learn more about interactive tables.';\n",
       "        element.innerHTML = '';\n",
       "        dataTable['output_type'] = 'display_data';\n",
       "        await google.colab.output.renderOutput(dataTable, element);\n",
       "        const docLink = document.createElement('div');\n",
       "        docLink.innerHTML = docLinkHtml;\n",
       "        element.appendChild(docLink);\n",
       "      }\n",
       "    </script>\n",
       "  </div>\n",
       "\n",
       "\n",
       "<div id=\"df-b1b348f5-2622-42cf-8886-1810a22c466e\">\n",
       "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-b1b348f5-2622-42cf-8886-1810a22c466e')\"\n",
       "            title=\"Suggest charts\"\n",
       "            style=\"display:none;\">\n",
       "\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
       "     width=\"24px\">\n",
       "    <g>\n",
       "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
       "    </g>\n",
       "</svg>\n",
       "  </button>\n",
       "\n",
       "<style>\n",
       "  .colab-df-quickchart {\n",
       "      --bg-color: #E8F0FE;\n",
       "      --fill-color: #1967D2;\n",
       "      --hover-bg-color: #E2EBFA;\n",
       "      --hover-fill-color: #174EA6;\n",
       "      --disabled-fill-color: #AAA;\n",
       "      --disabled-bg-color: #DDD;\n",
       "  }\n",
       "\n",
       "  [theme=dark] .colab-df-quickchart {\n",
       "      --bg-color: #3B4455;\n",
       "      --fill-color: #D2E3FC;\n",
       "      --hover-bg-color: #434B5C;\n",
       "      --hover-fill-color: #FFFFFF;\n",
       "      --disabled-bg-color: #3B4455;\n",
       "      --disabled-fill-color: #666;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart {\n",
       "    background-color: var(--bg-color);\n",
       "    border: none;\n",
       "    border-radius: 50%;\n",
       "    cursor: pointer;\n",
       "    display: none;\n",
       "    fill: var(--fill-color);\n",
       "    height: 32px;\n",
       "    padding: 0;\n",
       "    width: 32px;\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart:hover {\n",
       "    background-color: var(--hover-bg-color);\n",
       "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
       "    fill: var(--button-hover-fill-color);\n",
       "  }\n",
       "\n",
       "  .colab-df-quickchart-complete:disabled,\n",
       "  .colab-df-quickchart-complete:disabled:hover {\n",
       "    background-color: var(--disabled-bg-color);\n",
       "    fill: var(--disabled-fill-color);\n",
       "    box-shadow: none;\n",
       "  }\n",
       "\n",
       "  .colab-df-spinner {\n",
       "    border: 2px solid var(--fill-color);\n",
       "    border-color: transparent;\n",
       "    border-bottom-color: var(--fill-color);\n",
       "    animation:\n",
       "      spin 1s steps(1) infinite;\n",
       "  }\n",
       "\n",
       "  @keyframes spin {\n",
       "    0% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "      border-left-color: var(--fill-color);\n",
       "    }\n",
       "    20% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    30% {\n",
       "      border-color: transparent;\n",
       "      border-left-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    40% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-top-color: var(--fill-color);\n",
       "    }\n",
       "    60% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "    }\n",
       "    80% {\n",
       "      border-color: transparent;\n",
       "      border-right-color: var(--fill-color);\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "    90% {\n",
       "      border-color: transparent;\n",
       "      border-bottom-color: var(--fill-color);\n",
       "    }\n",
       "  }\n",
       "</style>\n",
       "\n",
       "  <script>\n",
       "    async function quickchart(key) {\n",
       "      const quickchartButtonEl =\n",
       "        document.querySelector('#' + key + ' button');\n",
       "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
       "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
       "      try {\n",
       "        const charts = await google.colab.kernel.invokeFunction(\n",
       "            'suggestCharts', [key], {});\n",
       "      } catch (error) {\n",
       "        console.error('Error during call to suggestCharts:', error);\n",
       "      }\n",
       "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
       "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
       "    }\n",
       "    (() => {\n",
       "      let quickchartButtonEl =\n",
       "        document.querySelector('#df-b1b348f5-2622-42cf-8886-1810a22c466e button');\n",
       "      quickchartButtonEl.style.display =\n",
       "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
       "    })();\n",
       "  </script>\n",
       "</div>\n",
       "    </div>\n",
       "  </div>\n"
      ]
     },
     "metadata": {},
     "execution_count": 13
    }
   ],
   "source": [
    "data = []\n",
    "for i in range(len(movies)):\n",
    "    data.append(\n",
    "        {\n",
    "            \"id\": movies.iloc[i][\"movie id\"],\n",
    "            \"title\": movies.iloc[i][\"title\"],\n",
    "            \"vector\": vectors[i],\n",
    "            \"genre\": movies.iloc[i][\"genres\"],\n",
    "        }\n",
    "    )\n",
    "pd.DataFrame(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5q8m6GMD7sGu"
   },
   "source": [
    "## Connect to LanceDB Cloud\n",
    "We can now connect to LanceDB Cloud, with the API key that is accquired from the dashboard. We'll also create a new table `movie_set` with the data we just created."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "id": "bboag_S67sGv",
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "outputId": "605c4cb4-5b0b-4306-f823-d79a0884c815"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "# you can simply replace the following line from the code copied from the dashboard\n",
    "# or substitute  with your project/api key\n",
    "uri = \"db://\" + project_slug\n",
    "db = lancedb.connect(uri, api_key=api_key, region=\"us-east-1\")\n",
    "try:\n",
    "    table = db.create_table(\"movie_set\", data=data)\n",
    "except:\n",
    "    table = db.open_table(\"movie_set\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KoiIKjZx7sGv"
   },
   "source": [
    "## Get the Recommendations\n",
    "Finally, we can create a function that takes a movie title and returns the top 5 similar movies. By searching in our vector store for the embeddings of the movie, we can return a dataframe of the most similar movies. We can also add some flair reading and displaying the links of each movie."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "8SVEEluC7sGv"
   },
   "outputs": [],
   "source": [
    "def get_recommendations(title):\n",
    "    pd_data = pd.DataFrame(data)\n",
    "    result = (\n",
    "        table.search(pd_data[pd_data[\"title\"] == title][\"vector\"].values[0])\n",
    "        .limit(5)\n",
    "        .to_pandas()\n",
    "    )\n",
    "\n",
    "    links = pd.read_csv(\n",
    "        \"./ml-latest-small/links.csv\",\n",
    "        header=0,\n",
    "        names=[\"movie id\", \"imdb id\", \"tmdb id\"],\n",
    "        converters={\"imdb id\": str},\n",
    "    )\n",
    "\n",
    "    ret = result[\"title\"].values.tolist()\n",
    "    for i in range(len(ret)):\n",
    "        link = links[links[\"movie id\"] == result[\"id\"].values[i]][\"imdb id\"].values[0]\n",
    "        link = \"https://www.imdb.com/title/tt\" + link\n",
    "        ret[i] = [ret[i], link]\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2mgrcOva7sGv"
   },
   "source": [
    "## Let's test it out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "KUVSrkew7sGw",
    "outputId": "99fa1814-e3d3-4f9d-8d36-451e905a7427"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[['Moana (2016)', 'https://www.imdb.com/title/tt3521164'],\n",
       " ['The Boss Baby (2017)', 'https://www.imdb.com/title/tt3874544'],\n",
       " ['The Book of Life (2014)', 'https://www.imdb.com/title/tt2262227'],\n",
       " ['Kubo and the Two Strings (2016)', 'https://www.imdb.com/title/tt4302938'],\n",
       " ['Bad Moms (2016)', 'https://www.imdb.com/title/tt4651520']]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_recommendations(\"Moana (2016)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ws889F097sGw",
    "outputId": "b0ffe57e-67c7-4ba2-d715-92390c42562a"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[['Rogue One: A Star Wars Story (2016)',\n",
       "  'https://www.imdb.com/title/tt3748528'],\n",
       " ['Wonder Woman (2017)', 'https://www.imdb.com/title/tt0451279'],\n",
       " ['Miss Sloane (2016)', 'https://www.imdb.com/title/tt4540710'],\n",
       " ['Passengers (2016)', 'https://www.imdb.com/title/tt1355644'],\n",
       " ['Man of Steel (2013)', 'https://www.imdb.com/title/tt0770828']]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_recommendations(\"Rogue One: A Star Wars Story (2016)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zsXoZEBL7sGw"
   },
   "source": [
    "## Tada!! your first movie recommendation system is live\n",
    "\n",
    "Of course, this won't be completely accurate. There are other ways improve the accuracy, such as `reducing the dimensions` of the original data, or filtering out users/movies with few ratings. But this is a good start to building a movie recommender system."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
